﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

/*
 * Essa é a classe encapsulada, é o primeiro dos minigames do jogo principal.
 * Eu decidi fazer uma classe pra cada jogo pois assim posso os manipular independentemente.
 * É mais prático porque se você ferrar algo fica mais fácil de debugar e consertar depois.
 */
namespace WindowsGame1
{

    //a classe fica dentro do namespace do jogo, namespace é como se fosse uma biblioteca
    //Você cria classes e funções e pode usar dentro dela
    class Jogo1
    {

        /*Essas são as variáveis do jogo1, por erro meu, elas são públicas (sempre que criar uma variável dentro de uma classe,
         * se não for declarado public or private ela é automáticamente public)
         * Não que isso interfira em algo, mas é pra manter o programa mais limpo e garantir que nada de errado vá acontecer
         * (nunca se sabe né)
         */
        Persona[] Inimigos;
        Persona Voce;

        /*
         * Essa é a função construtora, note que os parâmetros de entrada fazem a "comunicação" entre o programa principal e a classe,
         * pois como você não pode alterar diretamente as variáveis dessa classe, você cria uma função que capture os dados e insira nas funções
         * (é como uma função Set, mas eu decidi fazer direto na construtora pra economizar código)
         * Ah, e a função construtora é sempre public pois ela é usada quando você cria ela em outro ambiente
         * (o programa principal no caso)
         */
        public Jogo1(Texture2D a, Texture2D j)
        {
            Inimigos = new Persona[30]; //criando array de inimigos, note que Persona é outra classe dentro do namespace WindowsGame1
            //Aí como Jogo1 está dentro de WindowsGame1, eu posso usar Persona dentro de Jogo1
            Random _r = new Random();
            for (int b = 0; b < 30;b++ )
            {
                Inimigos[b] = new Persona(_r.Next(1024), 0 - (b * 28), a); //adicionando a Textura "a" nos inimigos
            }
            Voce = new Persona(400, 600, j); // adicionando a texutra "j" no seu personagem
        }

        /*
         * Essa é a função que vai resetar todos os objetos pros seus lugares iniciais
         * Ela é pública porque ela é usada pelo programa principal, e não por ela mesma
         */
        public void Reseta()
        {
            Random _r = new Random();
            for (int b = 0; b < 30; b++)
            {
                Inimigos[b].Pos.X = _r.Next(1024);
                Inimigos[b].Pos.Y = 0 - (b * 28);
            }
            Voce.Pos = new Vector2(400, 600);
        }

        /*
         * Função de update, pública porque é chamada por fora
         * Note que ela pega parâmetros do programa principal, o keyboardstate, o Tempo (classe criada no workspace) e Song
         */
        public char Update(KeyboardState ks, Tempo Time, Song[] Musicas)
        {
            if (Time.tempoRestante <= TimeSpan.FromSeconds(0))
            {
                Time.ResetaTempo();
                return '2';
            }

            if ((ks.IsKeyDown(Keys.Left) || (ks.IsKeyDown(Keys.A))) && Voce.Pos.X > 5)
            {
                if(ks.IsKeyDown(Keys.RightShift))
                {
                    Voce.Pos.X -= 3;
                }
                else
                {
                    Voce.Pos.X -= 5;
                }
            }
            if ((ks.IsKeyDown(Keys.Right) || (ks.IsKeyDown(Keys.D))) && Voce.Pos.X < 1019)
            {
                if (ks.IsKeyDown(Keys.RightShift))
                {
                    Voce.Pos.X += 3;
                }
                else
                {
                    Voce.Pos.X += 5;
                }
            }
            Random _r = new Random();
            foreach (Persona b in Inimigos)
            {
                b.Pos.Y += 5;
                if (b.Pos.Y > Voce.Pos.Y)
                {
                    b.Pos.X = _r.Next(1024);
                    b.Pos.Y = -30;
                }
            }
            if (Colide()) //Note que a função colide só é usada aqui, por isso é private, mas vou explicar melhor quando chegar nela
            {
                MediaPlayer.Play(Musicas[2]);
                Time.tempoRestante = TimeSpan.FromSeconds(5);
                return '0';
            }
            return '1';
        }
        /*
         * Função de desenho, chamada por fora, que precisa de um SpriteBatch para funcionar
         */
        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(Voce.Img, Voce.Pos, Color.White);
            foreach (Persona a in Inimigos)
            {
                spriteBatch.Draw(a.Img, a.Pos, Color.White);
            }
        }

        /*
         * Essa é a função que vai ver se os objetos colidem, é legal ressaltar vários pontos dela
         * Ela é private porque é chamada apenas dentro do Jogo1 por uma função do próprio jogo, ela não é necessária fora daqui
         * Como ela está dentro do Jogo1, ela não precisa que sejam passadas as variáveis de Jogo1 para manipulá-las
         * Ou seja, por fazer parte do jogo1 ela pode usar as variáveis de jogo1 como bem entender
         */
        private bool Colide()
        {
            Rectangle r1 = new Rectangle((int)Voce.Pos.X,(int) Voce.Pos.Y, (int)Voce.Img.Width, (int)Voce.Img.Height);
            foreach (Persona a in Inimigos)
            {
                Rectangle r2 = new Rectangle((int)a.Pos.X, (int)a.Pos.Y, (int)a.Img.Width, (int)a.Img.Height);
                if (r1.Intersects(r2))
                {
                    System.Threading.Thread.Sleep(1000);
                    return true;
                }
            }
            return false;
        }
    }
}
